using MediatR;
using Microsoft.Extensions.Logging;
using S.O.Api.Read.Application.Command.Medical;
using S.O.Domain.Dto.Output;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;

namespace S.O.Api.Read.Application.Handler.Medical
{
    /// <summary>
    /// 获取处方详情处理器
    /// 负责查询和返回指定处方的详细信息，包括药品明细
    /// </summary>
    public class GetPrescriptionDetailHandler : IRequestHandler<GetPrescriptionDetailCommand, APIResult<PrescriptionDto>>
    {
        /// <summary>
        /// 处方信息仓储
        /// </summary>
        private readonly IBaseRepository<PrescriptionModel> _prescriptionRepository;

        /// <summary>
        /// 处方药品明细仓储
        /// </summary>
        private readonly IBaseRepository<PrescriptionMedicineModel> _prescriptionMedicineRepository;

        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<GetPrescriptionDetailHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="prescriptionRepository">处方信息仓储</param>
        /// <param name="prescriptionMedicineRepository">处方药品明细仓储</param>
        /// <param name="logger">日志记录器</param>
        public GetPrescriptionDetailHandler(
            IBaseRepository<PrescriptionModel> prescriptionRepository,
            IBaseRepository<PrescriptionMedicineModel> prescriptionMedicineRepository,
            ILogger<GetPrescriptionDetailHandler> logger)
        {
            _prescriptionRepository = prescriptionRepository;
            _prescriptionMedicineRepository = prescriptionMedicineRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取处方详情命令
        /// </summary>
        /// <param name="request">查询命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处方详情</returns>
        public async Task<APIResult<PrescriptionDto>> Handle(GetPrescriptionDetailCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始查询处方详情，处方ID: {PrescriptionId}", request.PrescriptionId);

                // 查询处方基本信息
                var prescription = _prescriptionRepository.GetALL()
                    .Where(p => p.Id == request.PrescriptionId && !p.IsDeleted && p.IsEnable)
                    .FirstOrDefault();

                if (prescription == null)
                {
                    _logger.LogWarning("处方不存在，处方ID: {PrescriptionId}", request.PrescriptionId);
                    return new APIResult<PrescriptionDto>
                    {
                        Code = APIEnums.Error,
                        Msg = "处方不存在"
                    };
                }

                // 查询处方药品明细
                var medicines = _prescriptionMedicineRepository.GetALL()
                    .Where(m => m.PrescriptionId == request.PrescriptionId && !m.IsDeleted && m.IsEnable)
                    .ToList();

                // 转换为DTO
                var prescriptionDto = new PrescriptionDto
                {
                    Id = prescription.Id,
                    PatientId = prescription.PatientId,
                    PatientName = prescription.PatientName,
                    PrescriptionType = prescription.PrescriptionType,
                    Diagnosis = prescription.Diagnosis,
                    Remark = prescription.Remark,
                    Doctor = prescription.Doctor,
                    Status = prescription.Status,
                    CreateTime = prescription.CreateTime,
                    Medicines = medicines
                        .OrderBy(m => m.SortOrder)
                        .Select(m => new PrescriptionMedicineDto
                        {
                            Id = m.Id,
                            PrescriptionId = m.PrescriptionId,
                            MedicineName = m.MedicineName,
                            Specification = m.Specification,
                            Dosage = m.Dosage,
                            Frequency = m.Frequency,
                            Duration = m.Duration,
                            Usage = m.Usage,
                            Remark = m.Remark,
                            SortOrder = m.SortOrder
                        }).ToList()
                };

                _logger.LogInformation("处方详情查询完成，处方ID: {PrescriptionId}, 药品数量: {MedicineCount}", 
                    request.PrescriptionId, prescriptionDto.Medicines.Count);

                return new APIResult<PrescriptionDto>
                {
                    Code = APIEnums.Success,
                    Data = prescriptionDto,
                    Msg = "查询成功"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询处方详情时发生错误，处方ID: {PrescriptionId}", request.PrescriptionId);
                return new APIResult<PrescriptionDto>
                {
                    Code = APIEnums.Error,
                    Msg = "查询处方详情失败，请稍后重试"
                };
            }
        }
    }
}